package com.navinfo.platform.trip.common.arithmetic;

import com.navinfo.platform.trip.common.arithmetic.annotation.Arithmetic;
import com.navinfo.platform.trip.common.arithmetic.data.CommonData;
import com.navinfo.platform.trip.common.arithmetic.data.OuterStatisticData;
import com.navinfo.platform.trip.common.arithmetic.var.VarCarFlameout;
import com.navinfo.platform.trip.common.arithmetic.enums.EventType;
import com.navinfo.platform.trip.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.platform.trip.common.config.ConfigMap;

import java.util.Optional;

/**
 * 车辆熄火算法<br>
 * 输出：事件<br/>
 */
@Arithmetic(name = "熄火算法")
public class CarFlameout extends AbstractArithmetic<VarCarFlameout> {
    /**
     * 事件类型
     */
    private static final EventType EVENT_TYPE = EventType.flameout;
    /**
     * 熄火事件,转速阀值(单位：rpm)
     */
    private int eventRotationThreshold = ConfigMap.getInteger("Flameout_Rotation_Threshold");
    /**
     *  熄火事件，时长阀值 单位：ms
     */
    private long eventDurationThreshold =  ConfigMap.getLong("Flameout_Time_Threshold");

    /**
     * 判断当前点是否为熄火事件状态
     */
    private boolean isCurFlameout(int rotation) {
        return rotation <= eventRotationThreshold;
    }

    @Override
    public void calculate() {
        logger.debug("进入熄火算法.");
        VarCarFlameout varCarFlameout = getObj();
        CommonData commonData = getCommonData();

        boolean preStatus = varCarFlameout.isPreFlameout();
        boolean curStatus = isCurFlameout(commonData.getRotation());
        varCarFlameout.setPreFlameout(curStatus);
        logger.debug("熄火算法，熄火状态：preStatus:{},curStatus:{}.[terminalId:{}]", preStatus, curStatus, terminalId);

        switch (getEventStatus(preStatus, curStatus)) {
            case START:
                logger.debug("熄火算法，事件开始.[terminalId:{}]", terminalId);
                //事件持续时间为0，不写事件结束时间及gps信息
                startEventData(EVENT_TYPE);
                //累计时间重置
                varCarFlameout.setDuration(0);
                calcEventData();
                break;
            case IN:
                logger.debug("熄火算法，事件中.[terminalId:{}]", terminalId);
                calcEventData();
                break;
            case END:
                logger.debug("熄火算法，事件结束.[terminalId:{}]", terminalId);
                calcEventData();
                break;
            default:
                logger.debug("熄火算法，状态：上一次和本次都未，不进行计算.[terminalId:{}]", terminalId);
        }

        //行程结束时要清理对应的未结束事件，未满足时长阀值的事件，也进行输出
        if (commonData.isTripLastNode()) {
            Optional.ofNullable(drivingData.getEventData(EVENT_TYPE)).ifPresent(eventData ->{
                drivingData.addEventDataToList(eventData);
                drivingData.removeEventData(EVENT_TYPE);
                logger.debug("熄火算法，行程最后一个点处理，有未输出的熄火事件，进行输出[terminalId:{}]", terminalId);
            });
        }

        logger.debug("熄火算法结束.[terminalId:{}]", terminalId);
    }

    /**
     * 累加事件数据
     */
    private void calcEventData() {
        Optional.ofNullable(drivingData.getEventData(EVENT_TYPE)).ifPresent(eventData ->{
            VarCarFlameout varCarFlameout = getObj();
            varCarFlameout.setDuration(varCarFlameout.getDuration() + getCommonData().getDffTime());

            long durations = varCarFlameout.getDuration();
            if (durations >= eventDurationThreshold) {
                drivingData.addEventDataToList(eventData);
                drivingData.removeEventData(EVENT_TYPE);
                logger.debug("熄火算法，事件时间{},大于阀值，输出事件。[terminalId:{}]", durations, terminalId);
            } else {
                logger.debug("熄火算法，事件时间{},小于阀值，缓存事件，不输出。[terminalId:{}]", durations, terminalId);
            }
        });
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {

    }
}




